<?

/**
 * Class database 
 * Gère les connexions 
 */
class Database {
    
    protected $connections = array();
    
    /**
     */
    public function __construct(){
        $conf = Spyc::YAMLLoad(CONF_FILE);
        $dbconf = $conf["database"];
        if($dbconf){
				$connect = @new mysqli($dbconf["host"],$dbconf["user"],$dbconf["password"],$dbconf["db_name"]);
				if($connect->connect_errno != 0) {
					 throw new Exception ("MYSQL Error : ".$connect->connect_error);
				}
				$this->connection = $connect;
				$query = "SET NAMES 'utf8';";
				$connect->query($query);
				unset($connect);
		  }else{
				$this->connection = null;
		  }
    }
    public function getConnection(){
        return $this->connection;
    }
    /**
     * Enregistre un objet dans la base 
     */
    public function save(&$obj){        
        $query = $obj->getQueryInsert();
        $conn = $this->connection;
        $conn->query($query);
        if($conn->errno != 0) {
            throw new Exception ("MySQL Error : ".$conn->error."<br/>".$query);
        }
       	return $conn->insert_id;
    }
    /**
     * Test si un enregistrement existe dans la base 
     * Exemple pour un login 
     */
    public function exists($table,$query){
        $conn = $this->connection;
        
        if(count($query) == 0){
            throw new Exception ("No query");
        }
        $conditions = $this->constructConditions($query);
        $query = "SELECT count(*) as nb FROM ".strtolower($table)." WHERE $conditions";
        $res = $conn->query($query);
        if($conn->errno != 0){
            throw new Exception ($conn->error);
        }
        $line = $res->fetch_object();
        if($line->nb == 0) 
            return false;
        else
            return true;
    }
    /**
     * Construit la query
     */
    function constructConditions($query){
        $conditions = "";
        foreach($query as $var=>$val){
        	if(is_array($val)){
        		$conditions .= "$var ";
        		foreach($val as $operation=>$value){
        			$conditions .= "$operation \"$value\"";
        		}
        	}else{
	            if($conditions != "") $conditions .= "AND ";
	            $conditions .= "$var = \"".addslashes($val)."\" ";
        	}
        }
        return $conditions;
    }
    /** 
     * Renvoi 1 résultat dans un objet
     */
     
    public function fetchColumn($table,$column,$query){
        $conn = $this->connection;
        $conditions = $this->constructConditions($query);       
        $query = "SELECT $column FROM $table WHERE $conditions";
        $res = $conn->query($query);
        $line = $res->fetch_object();
        return $line->$column;
    }
    /**
     * Renvoi tous les enregistrements dans un tableau d'objet 
     */
    public function fetchAllModels($objectName,$query=array(),$sort=array(),$from="",$limit="",$debug=false){
    	
    	if(!class_exists($objectName)) include $objectName.".php";
    	
        $conn = $this->connection;
        if(count($query)>0){
        	$conditions = "WHERE ".$this->constructConditions($query);
        }else{
        	$conditions = "";
        }
        if($from == ""){
        	$from = strtolower($objectName);
        }
        $query = "SELECT * FROM $from ".$conditions;
        if(count($sort)>0){
        	$query .= " ORDER BY "; 
        	foreach($sort as $col=>$type){
        		$query .= $col." ".$type.","; 
        	}
        	$query = substr($query,0,-1);
        }
        if($limit != ""){
				$query .= " LIMIT $limit";
        }
        
        if($debug) echo $query;
        
        $res = $conn->query($query);
        if($conn->errno != 0) {
            throw new Exception ("MySQL Error : ".$conn->error."<br/>".$query);
        }
        $tab = array();
        while($line = $res->fetch_object()){
            $array = (array) $line;
            $obj = new $objectName();
            $obj->fromArray($array);
            if(isset($line->_id)){
            	$tab[$line->_id] = $obj;
            }else{
            	$tab[] = $obj;
            }
            foreach($obj as $var=>$val){
            	$obj->$var = stripslashes($val);
            }
        }
        return $tab;
    }
    /**
     * Renvoi une ligne dans un objet de type MODEL
     */
    public function fetchModels($objectName,$query){
    	
    	if(!class_exists($objectName)) include $objectName.".php";
    	
        $conn = $this->connection;
        $conditions = $this->constructConditions($query);       
        $query = "SELECT * FROM ".strtolower($objectName)." WHERE $conditions";
        $res = $conn->query($query);
        if($conn->errno != 0) {
            throw new Exception ("MySQL Error : ".$conn->error."<br/>".$query);
        }
        if($res->num_rows == 0) return null;
        $tab = array();
        $line = $res->fetch_object();
        $array = (array) $line;
        $obj = new $objectName();
        $obj->fromArray($array);
        return $obj;
    }
    /**
     * Supprime un enregistrement par son id
     * (_id)
     */
    public function remove($name,$id){
    	$conn = $this->connection;
    	if(is_array($id)){
    		foreach($id as $var=>$val){
    			$aConditions[] = "$var = \"$val\" ";
    		}
    		$condition = implode("AND",$aConditions);
    		$query = "DELETE FROM ".strtolower($name)." WHERE $condition;";
    		$res = $conn->query($query);
	        if($conn->errno != 0) {
	            throw new Exception ("MySQL Error : ".$conn->error."<br/>".$query);
	        }
    	}else{
	        $query = "DELETE FROM ".strtolower($name)." WHERE _id = '$id';";
	        $res = $conn->query($query);
	        if($conn->errno != 0) {
	            throw new Exception ("MySQL Error : ".$conn->error."<br/>".$query);
	        }
    	}
        return true;
    }
    public function update($obj){
		  
    }

}